home *** CD-ROM | disk | FTP | other *** search
- /* socket_ms . c
- #
- % Copyright (c) Jin Guojun
- %
- % Socket Master Server
- %
- % AUTHOR: Jin Guojun - LBL 1/1/93
- */
-
- #include <sys/asynch.h>
- #include <fcntl.h>
- #include "net_need.h"
-
- #ifndef SERVER
- #define SERVER "s_master"
- #endif
-
-
- static rtpmsg_hd msg_hdr;
- static char buf[1024], **plist;
- static int pnum, as, so;
- static magic_server ss[2]; /* 0 for TCP, and 1 for UDP */
- static struct sockaddr_in sain;
-
- build_arg_list(buf, tpp)
- char *buf, **tpp[];
- {
- register int i, n, p=n=0;
- char* *lp;
- Loop {
- n++;
- if (!(i = strchr(buf+p, Space))) break;
- i -= (int)buf;
- buf[i++] = 0; /* add terminator */
- p = i;
- } n++;
- verify_buffer_size(tpp, n--, sizeof(tpp), "tpp");
- lp = *tpp;
- lp[p=0] = "socket";
- for (i=p; i++ < n;) { /* start from second ap */
- lp[i] = buf + p;
- while (buf[p++]);
- }
- return n;
- }
-
- get_arg_list(rpp)
- int *rpp;
- {
- if (rpp)
- *rpp = (int)plist;
- return pnum;
- }
-
- x_extender_init(server_name, udp, buf_size)
- char *server_name;
- {
- if (!server_name)
- sprintf(server_name=buf, "%s", SERVER);
- sain.sin_port = htons(get_port(server_name, udp));
- sain.sin_family = AF_INET;
- sain.sin_addr.s_addr = INADDR_ANY;
- retryexi:
- ss[udp].so = so = socket(AF_INET, udp?SOCK_DGRAM:SOCK_STREAM, 0);
- if (buf_size < 4096 || buf_size > Max_WINDOW_SIZE)
- buf_size=Max_WINDOW_SIZE;
- if (udp && buf_size > UDP_BUF_LIMIT) buf_size =
- #ifdef sparc
- 28672;
- #else
- UDP_BUF_LIMIT;
- #endif
-
- if (!udp && bind(so, sain, sizeof(sain))) {
- close(so);
- if (sain.sin_port != SV_PORT) {
- sain.sin_port = SV_PORT;
- goto retryexi;
- }
- return prgmerr(0, "%d:bind[%d] -> port = %d",
- udp, so, sain.sin_port);
- } else if (buf_size > 4096 && setsockopt(so, SOL_SOCKET,
- SO_RCVBUF, &buf_size, sizeof(buf_size) ) < 0)
- return prgmerr(0, "sockbuf size %d", buf_size);
- if (!udp) listen(so, 2);
- return sain.sin_port;
- }
-
- FILE*
- x_extender(udp)
- {
- fd_set ready;
- register int i;
- int l;
- short psize;
- magic_server* lms=ss+udp;
-
- struct timeval to;
- FD_ZERO(&ready);
- FD_SET(so = lms->so, &ready);
- to.tv_sec = 0; to.tv_usec = 100000;
- if ((i=select(so+1, &ready, 0, 0, &to)) < 0 && debug)
- msg(" select %d(%d) ", i, so);
- if (FD_ISSET(so, &ready)) {
- FILE* fp;
- if (!lms->connected) {
- l = sizeof(sain);
- lms->as = as = accept(so, sain, &l);
- #ifdef _DEBUG_
- msg("select returns %d[%d]{%X}\t", so, as, i);
- #endif
- if (as > 0) {
- if (fcntl(as, F_SETOWN, getpid())<0)
- syserr("F_SETOWN %d", getpid());
- if (fcntl(as, F_SETFL, FASYNC)<0)
- syserr("F_SETEL FASYNC");
- lms->connected++;
- lms->stat = lms->dp = pnum = 0;
- if ((fp=fdopen(as, "rb"))) {
- if ((i=fgetc(fp)) == '#')
- if (!(l=fgetc(fp))) {
- fread(&psize, 1, sizeof(short), fp);
- i = htons(psize) + 1; /* NULL terminator */
- fread(&msg_hdr, 1, sizeof(msg_hdr), fp);
- fread(buf, 1, i, fp);
- gettimeofday(&lms->ts, 0);
- msg_hdr.tsr_s = lms->ts.tv_sec;
- msg_hdr.tsr_us = lms->ts.tv_usec;
- pnum = build_arg_list(buf, &plist);
- #ifdef _DEBUG_
- msg("params size %d {# %d}\n", i, pnum);
- #endif
- } else ungetc(l, fp), ungetc('#', fp);
- else ungetc(i, fp);
- #ifdef _DEBUG_
- msg("#1 = %d, #2 = %d\n", i, l);
- #endif
- return fp;
- } else return (FILE*)prgmerr(0, "fdopen");
- }
- } message("%d: something happened %d\n", lms->connected, as);
- } else if (lms->connected) {
- FD_ZERO(&ready);
- FD_SET(as, &ready);
- i = select(as+1, &ready, 0, 0, &to);
- #ifdef _DEBUG_
- msg("%d {%X} %d\n", i, FD_ISSET(as, &ready), to.tv_usec);
- #endif
- if (i && FD_ISSET(as, &ready)) {
- close(as); /* prepare to reconnect */
- lms->connected = 0;
- #ifdef _DEBUG_
- fprintf(stderr, "\t%d(%d): disconnect at {%X}\n",
- i, as, FD_ISSET(as, &ready));
- #endif
- }
- }
- fflush(stderr);
- return NULL;
- }
-
-